package mtg.collector.mtgc2.view;

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.util.HashMap;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import mtg.collector.mtgc2.utilities.AddCardState;
import mtg.collector.mtgc2.addutils.AddCardDisplayer;
import mtg.collector.mtgc2.addutils.AddCardWriter;
import mtg.collector.mtgc2.controller.MTGAddController;
import mtg.collector.mtgc2.model.MTGAddModel;
import mtg.collector.xml.org.Card;
import mtg.collector.xml.org.Deck;

import static mtg.collector.mtgc2.utilities.AddCardState.*;

/**
 * User Interface responsible for searching for MTG Cards. The AddManager is also responsible for adding
 * selected cards to the current deck. 
 * @author Eric Kisner
 */
public class AddManager extends AbstractMTGView {

    private static final int VIEW_WIDTH = 500;
    private static final int VIEW_HEIGHT = 750;
    private AddCardDisplayer acd;
    private MTGAddController controller;
    private Deck deck = null;
    private JFrame parent;

    /** Creates new form AddManager */
    public AddManager( JFrame parent ) {
        super( new Dimension( VIEW_WIDTH, VIEW_HEIGHT ) );
        this.parent = parent;
        initComponents();
        this.setVisible( true );
        initController();
    }

    public void finished() {
        if( !parent.isVisible() ) {
            parent.setVisible( true );
        }
    }

    public void setDeck( Deck deck ) {
        this.deck = deck;
    }

    private void initController() {
        MTGAddModel m = new MTGAddModel();
        controller = new MTGAddController();
        controller.addView( this );
        controller.addModel( m );
        controller.changeElementState( Idle );
    }

    @Override
    public void modelPropertyChange( PropertyChangeEvent e ) {
        if( e.getPropertyName().equals( MTGAddController.ELEMENT_STATE_PROPERTY ) ) {
            changeView( (AddCardState) e.getNewValue() );
        } else if( e.getPropertyName().equals( MTGAddController.ELEMENT_ADD_CARD_PROPERTY ) ) {
            addCardToDeck( (HashMap<JCheckBox, Card>) e.getNewValue() );
        }
    }

    private void changeView( AddCardState state ) {
        switch( state ) {
            case Idle:
                $enableAll();
                break;
            case Searching:
                $disableAll();
                break;
            case Start_Search:
                amntFoundLabel.setText( "" );
                if( validateTextField() ) {
                    acd = new AddCardDisplayer( this, controller, jtAddCard.getText() );
                    Thread t = new Thread( acd );
                    controller.changeElementState( Searching );
                    t.start();
                } else {
                    JOptionPane.showMessageDialog( this, "You must enter a valid card in order to search." );
                }
                break;
            case Adding:
                $disableAll();
                break;
            case Finished:
                $enableAll();
                break;
        }

    }

    private boolean validateTextField() {
        return !(jtAddCard.getText().equals( "" )
                 || jtAddCard.getText().length() < 3
                 || jtAddCard.getText().equals( "Enter Card" ));
    }

    private void addCardToDeck( HashMap<JCheckBox, Card> cardChoices ) {
        if( deck == null ) {
            JOptionPane.showMessageDialog( this, "You must select a deck to add cards to. "
                                                 + "Please exit and select a deck." );
            return;
        } else {
            AddCardWriter acw = new AddCardWriter( this, cardChoices, deck );
            acw.writeCards();
        }
    }

    private void $enableAll() {
        searchCardButton.setEnabled( true );
        addCardButton.setEnabled( true );
    }

    private void $disableAll() {
        searchCardButton.setEnabled( false );
        addCardButton.setEnabled( false );
    }

    //------------------------------------------------------------------------
    //-----------------------Generated Code-----------------------------------
    //------------------------------------------------------------------------
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings( "unchecked" )
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jtAddCard = new javax.swing.JTextField();
    searchCardButton = new javax.swing.JButton();
    amntFoundLabel = new javax.swing.JLabel();
    jPanel2 = new javax.swing.JPanel();
    jsCardResults = new javax.swing.JScrollPane();
    jPanel3 = new javax.swing.JPanel();
    addCardButton = new javax.swing.JButton();
    jMenuBar1 = new javax.swing.JMenuBar();
    jMenu1 = new javax.swing.JMenu();
    jmiExit = new javax.swing.JMenuItem();

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    setTitle("Add Cards Manager");
    setMinimumSize( new java.awt.Dimension( VIEW_WIDTH, VIEW_HEIGHT ));
    addWindowListener(new java.awt.event.WindowAdapter() {
      public void windowClosed(java.awt.event.WindowEvent evt) {
        formWindowClosed(evt);
      }
    });

    jPanel1.setName("jPanel1"); // NOI18N

    jtAddCard.setText("Enter Card");
    jtAddCard.setName("jtInputCard"); // NOI18N
    jtAddCard.setSelectionStart(0);
    jtAddCard.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyReleased(java.awt.event.KeyEvent evt) {
        jtAddCardKeyReleased(evt);
      }
    });

    searchCardButton.setText("Search for Card");
    searchCardButton.setName("searchCardButton"); // NOI18N
    searchCardButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        searchCardButtonActionPerformed(evt);
      }
    });

    amntFoundLabel.setFont(new java.awt.Font("Monospaced", 0, 12));
    amntFoundLabel.setName("amntFoundLabel"); // NOI18N

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel1Layout.createSequentialGroup()
        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(20, 20, 20)
            .addComponent(jtAddCard, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(searchCardButton))
          .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(76, 76, 76)
            .addComponent(amntFoundLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE)))
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    jPanel1Layout.setVerticalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel1Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jtAddCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(searchCardButton))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(amntFoundLabel)
        .addContainerGap(16, Short.MAX_VALUE))
    );

    jPanel2.setName("jPanel2"); // NOI18N

    jsCardResults.setBorder(null);
    jsCardResults.setForeground(new java.awt.Color(240, 240, 240));
    jsCardResults.setViewportBorder(javax.swing.BorderFactory.createTitledBorder(null, "Results", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 18))); // NOI18N
    jsCardResults.setName("jsResults"); // NOI18N
    jsCardResults.setOpaque(false);
    jsCardResults.setRequestFocusEnabled(false);
    jsCardResults.getVerticalScrollBar().setUnitIncrement(50);

    javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
    jPanel2.setLayout(jPanel2Layout);
    jPanel2Layout.setHorizontalGroup(
      jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jsCardResults, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
    );
    jPanel2Layout.setVerticalGroup(
      jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel2Layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jsCardResults, javax.swing.GroupLayout.DEFAULT_SIZE, 514, Short.MAX_VALUE))
    );

    jPanel3.setName("jPanel3"); // NOI18N

    addCardButton.setText("Add Card(s)");
    addCardButton.setName("addCardButton"); // NOI18N
    addCardButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        addCardButtonActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
    jPanel3.setLayout(jPanel3Layout);
    jPanel3Layout.setHorizontalGroup(
      jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
        .addContainerGap(52, Short.MAX_VALUE)
        .addComponent(addCardButton, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addGap(47, 47, 47))
    );
    jPanel3Layout.setVerticalGroup(
      jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel3Layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(addCardButton)
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    jMenuBar1.setName("jMenuBar1"); // NOI18N

    jMenu1.setText("File");
    jMenu1.setName("jMenu1"); // NOI18N

    jmiExit.setText("Exit");
    jmiExit.setName("miExit"); // NOI18N
    jmiExit.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jmiExitActionPerformed(evt);
      }
    });
    jMenu1.add(jmiExit);

    jMenuBar1.add(jMenu1);

    setJMenuBar(jMenuBar1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
      .addGroup(layout.createSequentialGroup()
        .addGap(112, 112, 112)
        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(117, Short.MAX_VALUE))
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
        .addContainerGap(96, Short.MAX_VALUE)
        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addGap(93, 93, 93))
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addGap(41, 41, 41)
        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addGap(18, 18, 18)
        .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap())
    );

    pack();
  }// </editor-fold>//GEN-END:initComponents

    private void jmiExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmiExitActionPerformed
        close( true );
}//GEN-LAST:event_jmiExitActionPerformed

	private void searchCardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchCardButtonActionPerformed
            javax.swing.SwingUtilities.invokeLater( new Runnable() {

                public void run() {
                    controller.changeElementState( Start_Search );
                }
            } );
	}//GEN-LAST:event_searchCardButtonActionPerformed

	private void jtAddCardKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jtAddCardKeyReleased
            if( evt.getKeyCode() == KeyEvent.VK_ENTER ) {
                controller.changeElementState( Start_Search );
            }
	}//GEN-LAST:event_jtAddCardKeyReleased

	private void addCardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addCardButtonActionPerformed
            controller.changeElementAddCard( acd.getCardChoices() );
	}//GEN-LAST:event_addCardButtonActionPerformed

	private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
            finished();
	}//GEN-LAST:event_formWindowClosed
    //<editor-fold defaultstate="collapsed" desc="Variable Declaration">
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton addCardButton;
  public javax.swing.JLabel amntFoundLabel;
  private javax.swing.JMenu jMenu1;
  private javax.swing.JMenuBar jMenuBar1;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JPanel jPanel2;
  private javax.swing.JPanel jPanel3;
  private javax.swing.JMenuItem jmiExit;
  public javax.swing.JScrollPane jsCardResults;
  private javax.swing.JTextField jtAddCard;
  public javax.swing.JButton searchCardButton;
  // End of variables declaration//GEN-END:variables
    //</editor-fold>
}
